package drds.global_transaction.global_transaction_manager.dubbo.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import drds.global_transaction.api.global_transaction_id_context.GlobalTransactionIdContexts;
import drds.global_transaction.resource_manager.ResourceManagerClient;
import drds.global_transaction.test.common.ApplicationKeeper;
import drds.global_transaction.global_transaction_manager.dubbo.AccountService;
import drds.global_transaction.global_transaction_manager.dubbo.Order;
import drds.global_transaction.global_transaction_manager.dubbo.OrderService;
import lombok.extern.slf4j.Slf4j;

/**
 * Please map$clientPortToRpcContextMap the follow VM arguments:
 *
 * <pre>
 *     -Djava.net.preferIPv4Stack=true
 * </pre>
 */
@Slf4j
public class OrderServiceImpl implements OrderService
{

	private AccountService accountService;

	private JdbcTemplate jdbcTemplate;

	public static void main(String[] args) throws Throwable
	{

		String applicationId = "dubbo-demo-order-server_addresss_look_up_service";
		String txServiceGroup = "my_test_tx_group";

		ResourceManagerClient.init(applicationId, txServiceGroup);

		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] { "dubbo-order-service" + ".xml" });
		applicationContext.getBean("server_addresss_look_up_service");
		JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");
		new ApplicationKeeper(applicationContext).keep();
	}

	@Override
	public Order create(String userId, String commodityCode, int orderCount)
	{
		log.info("Order Service begin ... globalTransactionIdWithAddressAndPort: " + GlobalTransactionIdContexts.getGlobalTransactionIdWithAddressAndPort());

		// 计算订单金额
		int orderMoney = calculate(commodityCode, orderCount);

		// 从账户余额扣款
		accountService.debit(userId, orderMoney);

		final Order order = new Order();
		order.userId = userId;
		order.commodityCode = commodityCode;
		order.count = orderCount;
		order.money = orderMoney;

		KeyHolder keyHolder = new GeneratedKeyHolder();

		jdbcTemplate.update(new PreparedStatementCreator()
		{

			@Override
			public PreparedStatement createPreparedStatement(Connection connection) throws SQLException
			{
				PreparedStatement pst = connection.prepareStatement("insert into order_tbl (user_id, commodity_code, count, money) values (?, ?, ?, ?)", PreparedStatement.RETURN_GENERATED_KEYS);
				pst.setObject(1, order.userId);
				pst.setObject(2, order.commodityCode);
				pst.setObject(3, order.count);
				pst.setObject(4, order.money);
				return pst;
			}
		}, keyHolder);

		order.id = (long) keyHolder.getKey();

		log.info("Order Service End ... Created " + order);

		return order;
	}

	public void setAccountService(AccountService accountService)
	{
		this.accountService = accountService;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate)
	{
		this.jdbcTemplate = jdbcTemplate;
	}

	private int calculate(String commodityId, int orderCount)
	{
		return 200 * orderCount;
	}
}
